package com.jindy.module.oaPayApproval.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.jindy.activiti.service.IProcessService;
import com.jindy.common.constant.Constants;
import com.jindy.common.exception.base.BaseException;
import com.jindy.common.utils.DateUtils;
import com.jindy.common.utils.SecurityUtils;
import com.jindy.common.utils.StringUtils;
import com.jindy.jpush.utils.UniJpushUtils;
import com.jindy.module.approvalRecord.domain.ApprovalRecord;
import com.jindy.module.approvalRecord.mapper.ApprovalRecordMapper;
import com.jindy.module.jpush.mapper.JpushMapper;
import com.jindy.module.oaEvectionApproval.domain.SyOaEvection;
import com.jindy.module.oaEvectionApproval.mapper.SyEvectionTripMapper;
import com.jindy.module.oaEvectionApproval.service.ISyEvectionTripService;
import com.jindy.module.oaEvectionApproval.service.impl.SyOaEvectionServiceImpl;
import com.jindy.module.oaPayApproval.mapper.SyPayDetailMapper;
import com.jindy.module.oaPayApproval.mapper.SyPayFormMapper;
import com.jindy.module.oaPayApproval.service.ISyPayDetailService;
import com.jindy.module.oaPayApproval.service.ISyPayFormService;
import com.jindy.module.oacopy.service.ISyOaCopyService;
import com.jindy.module.oacopyconfig.domain.SyOaCopyConfig;
import com.jindy.module.oacopyconfig.mapper.SyOaCopyConfigMapper;
import com.jindy.module.serialNum.service.ISySerialNumTService;
import com.jindy.module.syTableRecord.service.ISyTableRecordTService;
import com.jindy.system.domain.SysOperLog;
import com.jindy.system.domain.SysUserRoleDeptInfo;
import com.jindy.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jindy.module.oaPayApproval.mapper.SyOaPayMapper;
import com.jindy.module.oaPayApproval.domain.SyOaPay;
import com.jindy.module.oaPayApproval.service.ISyOaPayService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 财务付款审批Service业务层处理
 * 
 * @author jindy
 * @date 2023-06-16
 */
@Service
public class SyOaPayServiceImpl implements ISyOaPayService 
{
    private static final Logger LOGGER = LoggerFactory.getLogger(SyOaPayServiceImpl.class);

    @Autowired
    private SyOaPayMapper syOaPayMapper;

    @Autowired
    private ISyPayDetailService iSyPayDetailService;

    @Autowired
    private ISyPayFormService iSyPayFormService;

    @Autowired
    private SyEvectionTripMapper syEvectionTripMapper;

    @Autowired
    private IProcessService processService;


    /**
     * 抄送Service
     */
    @Resource
    private ISyOaCopyService syOaCopyService;

    /**
     * 配置表
     */
    @Resource
    private SyOaCopyConfigMapper syOaCopyConfigMapper;

    /**
     * 生成流水单号Service
     */
    @Resource
    private ISySerialNumTService serialNumTService;

    /**
     * 生成流水单号Service
     */
    @Resource
    private ApprovalRecordMapper approvalRecordMapper;

    /**
     * 用户Service
     */
    @Resource
    private ISysUserService sysUserService;

    /**
     * 设备Mapper
     */
    @Resource
    private JpushMapper jpushMapper;

    /**
     * 存储表Service
     */
    @Resource
    private ISyTableRecordTService iSyTableRecordTService;

    /**
     * 出差行程Service
     */
    @Resource
    private ISyEvectionTripService iSyEvectionTripService;

    /**
     * 查询财务付款审批
     * 
     * @param id 财务付款审批主键
     * @return 财务付款审批
     */
    @Override
    public SyOaPay selectSyOaPayById(Long id)
    {
        return syOaPayMapper.selectSyOaPayById(id);
    }

    /**
     * 查询财务付款审批列表
     * 
     * @param syOaPay 财务付款审批
     * @return 财务付款审批
     */
    @Override
    public List<SyOaPay> selectSyOaPayList(SyOaPay syOaPay)
    {
        if (!SecurityUtils.isAdmin(SecurityUtils.getLoginUser().getUser().getUserId())){
            syOaPay.setCreateBy(SecurityUtils.getUsername());
        }
        List<SyOaPay> list = syOaPayMapper.selectSyOaPayList(syOaPay);

        list=this.switchSyTrip(list);

        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(item -> {
                try {
                    processService.richProcessField(item);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        return list;
//        return syOaPayMapper.selectSyOaPayList(syOaPay);
    }

    /**
     * 新增财务付款审批
     * 
     * @param syOaPay 财务付款审批
     * @return 结果
     */
    @Override
    public int insertSyOaPay(SyOaPay syOaPay)
    {
        // 生成流水单号
        String serialNum = serialNumTService.generateSerialNum("CWFKSP");
        if (StringUtils.isBlank(serialNum)) {
            throw new BaseException("新增财务付款审批-获取财务付款单号失败");
        }

        //保存相应的报销明细表id
        String ids="";
        if(syOaPay.getSyPayDetailList() != null && syOaPay.getSyPayDetailList().size()>0){
            ids=this.insertDetails(syOaPay);
            syOaPay.setSyPayDetailId(ids);
        }

        //保存相应的报销表格表id
        String ids2="";
        if(syOaPay.getSyPayFormList() != null && syOaPay.getSyPayFormList().size()>0){
            ids2=this.insertForm(syOaPay);
            syOaPay.setSyPayFormId(ids2);
        }

        //获取申请人信息
        Long userId=SecurityUtils.getLoginUser().getUser().getUserId();
        syOaPay.setApplyUserId(userId.toString());
        syOaPay.setApplyUserName(SecurityUtils.getLoginUser().getUser().getUserName());

        //获取申请时间
        syOaPay.setApplyTime(DateUtils.getNowDate());

        syOaPay.setSerialNum(serialNum);
        syOaPay.setBusinessStatus(Constants.DRAFT);
        syOaPay.setCreateTime(DateUtils.getNowDate());
        iSyTableRecordTService.saveEntityAndTable(syOaPay,serialNum);
        return syOaPayMapper.insertSyOaPay(syOaPay);
//        syOaPay.setCreateTime(DateUtils.getNowDate());
//        return syOaPayMapper.insertSyOaPay(syOaPay);
    }

    /**
     * 修改财务付款审批
     * 
     * @param syOaPay 财务付款审批
     * @return 结果
     */
    @Override
    public int updateSyOaPay(SyOaPay syOaPay)
    {
        syOaPay.setUpdateTime(DateUtils.getNowDate());
        return syOaPayMapper.updateSyOaPay(syOaPay);
    }

    /**
     * 批量删除财务付款审批
     * 
     * @param ids 需要删除的财务付款审批主键
     * @return 结果
     */
    @Override
    public int deleteSyOaPayByIds(Long[] ids)
    {
        return syOaPayMapper.deleteSyOaPayByIds(ids);
    }

    /**
     * 删除财务付款审批信息
     * 
     * @param id 财务付款审批主键
     * @return 结果
     */
    @Override
    public int deleteSyOaPayById(Long id)
    {
        return syOaPayMapper.deleteSyOaPayById(id);
    }

    //报销明细分条插入，记录id
    public String insertDetails(SyOaPay syOaPay){
        String ids="";
        for (int i=0;i<syOaPay.getSyPayDetailList().size();i++){
            iSyPayDetailService.insertSyPayDetail(syOaPay.getSyPayDetailList().get(i));
            ids+=syOaPay.getSyPayDetailList().get(i).getId()+",";
        }
        return ids;
    }

    //报销明细分条插入，记录id
    public String insertForm(SyOaPay syOaPay){
        String ids="";
        for (int i=0;i<syOaPay.getSyPayFormList().size();i++){
            iSyPayFormService.insertSyPayForm(syOaPay.getSyPayFormList().get(i));
            ids+=syOaPay.getSyPayFormList().get(i).getId()+",";
        }
        return ids;
    }

    //查询信息时加入报销明细信息与报销表格信息
    public List<SyOaPay> switchSyTrip(List<SyOaPay> list){
        for(int i=0;i<list.size();i++){
            if(list.get(i).getSyPayDetailId() != null && !list.get(i).getSyPayDetailId().equals("")){
                String[] id=list.get(i).getSyPayDetailId().split(",");
                Long[] ids=new Long[id.length];
                for(int j=0;j<id.length;j++){
                    ids[j]=Long.valueOf(id[j]);
                }
                list.get(i).setSyPayDetailList(iSyPayDetailService.selectSyPayDetailsListByIds(ids));
            }
            if(list.get(i).getSyPayFormId() != null && !list.get(i).getSyPayFormId().equals("")){
                String[] id=list.get(i).getSyPayDetailId().split(",");
                Long[] ids=new Long[id.length];
                for(int j=0;j<id.length;j++){
                    ids[j]=Long.valueOf(id[j]);
                }
                list.get(i).setSyPayFormList(iSyPayFormService.selectSyPayFormsListByIds(ids));
            }
        }
        return list;
    }


    /**
     * 提交申请
     *
     * @param syOaPay
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void submitApply(SyOaPay syOaPay) throws Exception {
        // 初始化值
        Map<String, Object> variables = createVariables(syOaPay);
        // 启动流程
        processService.submitApply(syOaPay, "pay", variables);
        // 添加抄送人
        syOaCopyService.addCopyUsers("CWFKSP", syOaPay.getId());
        //新增审批记录
        List<Long> longs = addApprovalRecord(syOaPay, variables);
        // 通知审批人
        sendApproveMessage(longs);
        syOaPay.setBusinessStatus(Constants.APPROVE);
        updateSyOaPay(syOaPay);
    }

    /**
     * 逻辑流初始化
     *
     * @param syOaPay
     * @return
     */
    public Map<String, Object> createVariables(SyOaPay syOaPay) {
        Map<String, Object> var = new HashMap<>(500);
        // 判断申请人是否是主管
        List<SysUserRoleDeptInfo> userList = sysUserService.selectUsersByUserName(syOaPay.getApplyUserName());

        if (CollectionUtils.isEmpty(userList)) {
            throw new BaseException("财务付款审批-判断是否为直接主管集合为空");
        }

        //申请人不是主管，则先由部门主管审批
        if (!userList.get(0).getUserName().equals(userList.get(0).getLeader())){
            var.put("isdeptleader", false);
            var.put("deptleader",userList.get(0).getLeader());
            var.put("deptleaderId",userList.get(0).getLeaderId());
        }
        else{
            var.put("isdeptleader", true);
        }

        //财务审批
        SyOaCopyConfig syOaCopyConfig = new SyOaCopyConfig();
        syOaCopyConfig.setNumber("CWFKSP_FIN");
        List<SyOaCopyConfig> syOaCopyConfigs = syOaCopyConfigMapper.selectSyOaCopyConfigList(syOaCopyConfig);
        if (CollectionUtils.isEmpty(syOaCopyConfigs)) {
            throw new BaseException("createVariables", "财务付款审批获取财务失败");
        }
        var.put("finance",syOaCopyConfigs.get(0).getCopyUserName());
        var.put("financeId",syOaCopyConfigs.get(0).getCopyUserId());

        //财务主管审批
        SyOaCopyConfig syOaCopyConfig2 = new SyOaCopyConfig();
        syOaCopyConfig2.setNumber("CWFKSP_FIN_LEADER");
        List<SyOaCopyConfig> syOaCopyConfigs2 = syOaCopyConfigMapper.selectSyOaCopyConfigList(syOaCopyConfig2);
        if (CollectionUtils.isEmpty(syOaCopyConfigs2)) {
            throw new BaseException("createVariables", "财务付款审批获取财务失败");
        }
        var.put("finleader",syOaCopyConfigs2.get(0).getCopyUserName());
        var.put("finleaderId",syOaCopyConfigs2.get(0).getCopyUserId());

        //出纳审批
        SyOaCopyConfig syOaCopyConfig3 = new SyOaCopyConfig();
        syOaCopyConfig3.setNumber("CWFKSP_CN");
        List<SyOaCopyConfig> syOaCopyConfigs3 = syOaCopyConfigMapper.selectSyOaCopyConfigList(syOaCopyConfig3);
        if (CollectionUtils.isEmpty(syOaCopyConfigs3)) {
            throw new BaseException("createVariables", "财务付款审批获取财务失败");
        }
        var.put("cn",syOaCopyConfigs3.get(0).getCopyUserName());
        var.put("cnId",syOaCopyConfigs3.get(0).getCopyUserId());

        return var;
    }

    /**
     * 新增审批记录
     * @param syOaPay
     * @param map
     * @return
     */
    private List<Long> addApprovalRecord(SyOaPay syOaPay, Map<String, Object> map) {
        List<Long> list = new ArrayList<>();
        int sequence = 1;
        //  发起人
        ApprovalRecord firstApprovalRecord = getApprovalRecord(syOaPay);
        firstApprovalRecord.setSequence(sequence);
        firstApprovalRecord.setApprovalStatus(Constants.COMPLETED);
        firstApprovalRecord.setTypeOperation(Constants.AGREE);
        firstApprovalRecord.setBusinessStatus(Constants.APPROVE);
        firstApprovalRecord.setApproverId(Long.valueOf(syOaPay.getApplyUserId()));
        firstApprovalRecord.setApproverName(syOaPay.getApplyUserName());
        approvalRecordMapper.insertApprovalRecord(firstApprovalRecord);

        //不是主管，则需要主管审批
        if (!(boolean)map.get("isdeptleader")){
            sequence++;
            //  第一审批人
            ApprovalRecord secondApprovalRecord = getApprovalRecord(syOaPay);
            secondApprovalRecord.setSequence(sequence);
            secondApprovalRecord.setApprovalStatus(Constants.APPROVE);
            String deptleaderId=map.get("deptleaderId").toString();
            secondApprovalRecord.setApproverId(Long.parseLong(deptleaderId));
            secondApprovalRecord.setApproverName((String) map.get("deptleader"));
            approvalRecordMapper.insertApprovalRecord(secondApprovalRecord);
            list.add(Long.parseLong(deptleaderId));
        }

        sequence++;
        //  第二审批人
        ApprovalRecord thirdApprovalRecord = getApprovalRecord(syOaPay);
        thirdApprovalRecord.setSequence(sequence);
        thirdApprovalRecord.setApprovalStatus(Constants.APPROVE);
        String financeId=map.get("financeId").toString();
        thirdApprovalRecord.setApproverId(Long.parseLong(financeId));
        thirdApprovalRecord.setApproverName((String) map.get("finance"));
        approvalRecordMapper.insertApprovalRecord(thirdApprovalRecord);
        list.add(Long.parseLong(financeId));

        sequence++;
        //  第三审批人
        ApprovalRecord fourthApprovalRecord = getApprovalRecord(syOaPay);
        fourthApprovalRecord.setSequence(sequence);
        fourthApprovalRecord.setApprovalStatus(Constants.APPROVE);
        String finleaderId=map.get("finleaderId").toString();
        fourthApprovalRecord.setApproverId(Long.parseLong(finleaderId));
        fourthApprovalRecord.setApproverName((String) map.get("finleader"));
        approvalRecordMapper.insertApprovalRecord(fourthApprovalRecord);
        list.add(Long.parseLong(finleaderId));

        sequence++;
        //  第四审批人
        ApprovalRecord fifthApprovalRecord = getApprovalRecord(syOaPay);
        fifthApprovalRecord.setSequence(sequence);
        fifthApprovalRecord.setApprovalStatus(Constants.APPROVE);
        String cnId=map.get("cnId").toString();
        fifthApprovalRecord.setApproverId(Long.parseLong(cnId));
        fifthApprovalRecord.setApproverName((String) map.get("cn"));
        approvalRecordMapper.insertApprovalRecord(fifthApprovalRecord);
        list.add(Long.parseLong(cnId));

        return list;
    }

    /**
     * 获取审批记录对象
     *
     * @param syOaPay
     * @return
     */
    private ApprovalRecord getApprovalRecord(SyOaPay syOaPay) {
        ApprovalRecord approvalRecord = new ApprovalRecord();
        approvalRecord.setSerialNum(syOaPay.getSerialNum());
        approvalRecord.setUserId(Long.valueOf(syOaPay.getApplyUserId()));
        approvalRecord.setOrderId(syOaPay.getId());
        approvalRecord.setUserName(syOaPay.getApplyUserName());
        approvalRecord.setUpdateTime(DateUtils.parseDate(DateUtils.getTime()));
        approvalRecord.setUpdateBy(syOaPay.getApplyUserName());
        approvalRecord.setCreateBy(syOaPay.getApplyUserName());
        approvalRecord.setCreateTime(DateUtils.parseDate(DateUtils.getTime()));
        return approvalRecord;
    }

    /**
     * 给审批人推送消息
     * @param addJpushList
     */
    private void sendApproveMessage(List<Long> addJpushList) {
        try {
            List<String> addRegIds = jpushMapper.selectRegistrationIdsByUserIds(addJpushList);
            if (!CollectionUtils.isEmpty(addRegIds)){
                UniJpushUtils.sendApproveMessage(addRegIds);
            }
        } catch (Exception e) {
            LOGGER.error("财务付款审批审批人推送通知失败",e);
        }
    }

}
